Code and Notes (Week 1 Wednesday)
Table of Contents
1 Live code
This is all the code I wrote during the lecture. No guarantee that it makes any sense out of context.
-- modules are mainly used for namespaces -- to acces that from outside -- I would go FirstLecture.x module FirstLecture where {- Alternative titles: Introduction to Mathematically Structured Programming I can't believe it's not a Haskell course! -} -- inline comment -- Ints, Doubles {- int square(int x) { return(x*x); } -} -- the first line is a *function signature* -- it specifies the name and type of the function -- function types look like this: -- a -> b -- a is the *domain* of the function -- aka the argument type -- b is the *codomain* of the function -- aka the return type square :: Int -> Int -- next comes the function *definition* -- the LHS names the parameter x -- the RHS is an expression describing -- the return value of the function square x = x*x {- This is (kind of) a mathematical function: it maps an input to an output, and does absolutely nothing else -} {- These are *not* like variables in C, Java, Python... They're more like constants. I will sometimes call them variables anyway. (More proper term might be "bindings") -} --x :: Int --x = 7 myLogBase :: Double -> Double -> Double myLogBase = logBase {- Q: Why doesn't this function specify its arguments? A: I could have but it doesn't matter. If I have a function f that takes an argument x, and returns g x then f = g technical term: eta-equivalence When we make a declaration name <args> = <body> The LHS and RHS need to have the same type -} myOtherLogBase :: Double -> Double -> Double myOtherLogBase x y = logBase x y {- myLogBase is a function, which -- given a Double, returns: -- a function of type Double -> Double -} {- Functions are first-class citizens: functions are values that can be used in all the same ways as Doubles, Ints, Bools, ... You can have lists of functions You can give functions as arguments to other functions You can return functions from functions -} {- myLogBase 10 *is* the 10:th logarithm function myLogBase 2 is the binary logarithm function -} -- Technically, haskell functions are -- from exactly one argument -- to exactly one argument {- This technique is called Currying Because this is done *all the time* There's some syntactical conventions: Function application is left associative f x y = (f x) y Conversely, the arrow in type signatures (called function arrow) is right associative a -> b -> c this means a -> (b -> c) -} {- The arithmetic operators + - * / div are also curried functions 1 + 2 is sugar for (+) 1 2 1 `div` 2 is sugar for div 1 2 Symbolic identifiers are infix, but can be treated as prefix by surrounding them with parens Alphanumeric identifiers are prefix, but can be treated as infix by surrounding them with backticks -} {- This declaration defines the constant x in terms of itself "Let x = x + 1" In order to calculate the value of x: Step 1: get the value x Step 2: add 1 to the value of x -} --x = x + 1 -- declarative vs imperative programming -- Function application syntax -- Chars, Strings -- Lists -- String in Haskell is a -- synonym of [Char] -- List in Haskell (singly-linked lists) -- are of two primitive kinds -- the empty list: [] -- cons blocks (:) -- If x is an element -- and xs is a list -- then x:xs is also a list -- [a,b,c] is sugar for -- a:b:c:[] -- Every element in a list must have -- the same type -- Multi-argument functions -- Pairs -- if x and y are values of possibly types -- x::a and y::b -- then (x,y) : (a,b) divmod :: Int -> Int -> (Int,Int) divmod x y = (x `div` y, x `mod` y)